# -*- coding: utf-8 -*-

'''
Created on 26/11/2011

@author: Luis M. Ugalde
www.forondarena.net

Copyright © 2011 Luis M. Ugalde
Licensed under the terms of the MIT License
(see LICENSE file for details)

This software can't be considered to be even in Alpha state. It still needs a lot of work.
'''


from . import abstractwriter
import zmq
import pickle
from writers import writerexception


class WriterFile(abstractwriter.AbstractWriter):
    '''
    Class to write records to regular files. It reads pickle records and stores them in a file as plain text.
    This writer will know when to end with a special END message sent from the State Store.
    '''


    def __init__(self):
        print self.__class__.__name__ + ": WriterFile instance created"
        abstractwriter.AbstractWriter.__init__(self)
    
    
    def consumeLine(self, line):
        '''
        '''
        
        data = pickle.loads(line)

        if data == 'NODATA':
            if __debug__:
                print "{}-{}: Received nodata signal.".format(self.__class__.__name__, self.filename)
            return
        
        if __debug__:
            print "{}-{}: Writing record: {}.".format(self.__class__.__name__, self.filename, data)

        for key, value in data.items():
            self.file.write('{}: '.format(key))
            try:
                while value:
                    tmpdata = value.pop()
                    self.file.write('\n\t{}\n'.format(tmpdata))
            except AttributeError:
                self.file.write('{}\n'.format(value))
        

        self.file.write('---------------------------------------------------\n')
        self.file.flush()


    def putRecords(self):
        '''
        Write records to the destination file.
        '''

        mustexit = 0
        idlesockets = 0
        
        while True:
            socks = dict(self.poller.poll(3000))
            if socks:
                idlesockets = 0
                for i in self.statestoreconnectsockets:
                    if i in socks and socks.get(i) == zmq.POLLIN:
                        line = i.recv()
                        try:
                            self.consumeLine(line)
                        except IOError:
                            if __debug__:
                                print "{}-{}: Error writing record. Exiting: {}.".format(self.__class__.__name__, self.filename, line)
                            break
                if self.statestoreconnectnotifysocket in socks and socks.get(self.statestoreconnectnotifysocket) == zmq.POLLIN:
                    line = self.statestoreconnectnotifysocket.recv()
                    print "{}-No bind notify writer: The line is {}.".format(self.__class__.__name__, line)
                    if line == 'END':
                        print self.__class__.__name__ + ": Received END signal. Trying to end Writer."
                        mustexit = 1
            else:
                if mustexit > 0:
                    print "{}-{}: No data left at writer for 3 seconds wind end signal. Ending.".format(self.__class__.__name__, self.filename)
                    break
                if idlesockets > 3:
                    print "{}-{}: Too long with no activity from sockets. Should probably do something".format(self.__class__.__name__, self.filename)
                    idlesockets = 0
                idlesockets += 1

        self.closeSources()
        self.closeBindWriter()
        self.closeNotifySources()
        self.closeContext()


    def setBindWriter (self, dstfilename = ""):
        '''
        The destination for a file writer is  a regular text file.
        '''

        self.filename = dstfilename


    def bindWriter(self):
        '''
        Open the file set with setBindWriter
        '''
        
        # Let the exception raise or catch it here?
        
        print "{}: Opening file for writing: {}".format(self.__class__.__name__, self.filename)
        self.file = open(self.filename, 'a')


    def closeBindWriter(self):
        '''
        Close the file
        '''
        
        print "{}: Closing file: {}".format(self.__class__.__name__, self.filename)
        self.file.close()


if __name__ == '__main__':
    print "Please, do not run this"
